var utils = {
    /**
     * 获取非内联样式
     * @param {DOMobject} obj 要获取的属性的DOM对象
     * @param {string} attr   要获取的属性名
     * @return {string} String attr的样式值
     */

    getstyle(obj,attr){
        if(obj.currentStyle){
            return obj.currentStyle[attr]
        }else{
            return getComputedStyle(obj,false)[attr]
        }
    },

    /**
     * 设置监听
     * @param {DOMobject} obj 要设置监听的对象 
     * @param {string} type   设置的事件类型 
     * @param {function} fn   监听的函数事件 
     * @param {boolean} iscaptrue 设置事件是捕获还是冒泡
     */

    on (obj,type,fn,iscaptrue){
        if(iscaptrue == undefined) iscaptrue = false
        if(window.attachEvent){
            obj.attachEvent('on'+type,fn)
        }else{
            obj.addEventListener(type,fn,iscaptrue)
        }
    },

    /**
     * 移除监听
     * @param {DOMobject} obj 要设置监听的对象 
     * @param {string} type   设置的事件类型 
     * @param {function} fn   监听的函数事件 
     * @param {boolean} iscaptrue 设置事件是捕获还是冒泡
     */

    off (obj,type,fn,iscaptrue){
        if(iscaptrue == undefined) iscaptrue = false
        if(window.detachEvent){
            obj.detachEvent('on'+type,fn)
        }else{
            obj.removeEventListener(type,fn,iscaptrue)
        }
    },

    /**
     * 匀速运动
     * @param {DOMobject} ele 设置要运动的对象 
     * @param {string} attr   设置运动的属性名
     * @param {number} end    设置运动的终点值 单位px
     * @param {number} turation 运动所需要的总事件 ms 
     * @param {function} fn   运动结束后，所进行的操作（回调函数）
     */

    move(ele,attr,end,turation,fn){
        // 获取开始坐标值
        var start = parseInt(utils.getstyle(ele,attr))
        //获取一共要运动的距离
        var distance = end - start  
        // 获取定时器要运动多少次
        var steps = parseInt(turation / 20)  
        // 获取每一步的速度
        var speed = distance / steps
        clearInterval(ele.timer)
        // 开始运动
        var n = 0
    ele.timer =  setInterval(function(){
            n++
            ele.style[attr] = start + n*speed + 'px'
            if(n==steps){
                ele.style[attr] = end+'px'
                clearInterval(ele.timer)
                fn && fn()
            }
        },20) 
    },
    /**
     * 缓冲运动
     * @param {DOMObject} ele 作用的对象 
     * @param {string} attr   操作的属性名
     * @param {number} end    终点值 
     * @param {function} fn   运动结束后的回调函数
     */
    bfmove(ele,attr,end,fn){
        //获取最初的位置
        var strat = parseInt(utils.getstyle(ele,attr))
        //清除前一次的定时器
        clearInterval(ele.timer)
        ele.timer = setInterval(function(){
            // 获取实时的路程距离
            var distance = end-strat
            // 获取实时距离的1/10
            var speed = distance>0 ? Math.ceil(distance / 10) : Math.floor(distance / 10)
            // console.log(speed) 
            // 得到已经运动的距离
            strat += speed
            ele.style[attr] = strat + 'px'
            if(strat == end){
                clearInterval(ele.timer)
                fn && fn()
            }
        },20)
    },

    /**
     * 获取盒子到body 的距离
     * @param {DOMobject} ele 获取坐标的元素
     * @return {Object}  得到坐标值
     */
    getBodyPos(ele){
        var left = 0,top = 0;
        while(ele.offsetParent){
            left += ele.offsetLeft + ele.clientLeft
            top += ele.offsetTop + ele.clientTop
            ele = ele.offsetParent
        }
        return {left,top}
    },

    /**
     * 设置cookie
     * @param {string} key       要存储的cookie的名称
     * @param {string} value     要存储的cookie的值
     * @param {object} options   {path，expires} 例 {path:'/',expirse:1} 存储根路径，有效期一天，默认path路径为'/'
     */
    setCookie (key,value,options) {
        options = options || {path : '/'}
        if(!options.path){
            options.path = '/'
        }
        //合并写
        // options = options ? Object.assign({path:'/'},options) : {path:'/'}

        var str = `${key}=${encodeURIComponent(value)};path=${options.path}`
        if(options.expires){
            var d = new Date()
            d.setDate(d.getDate()+options.expires)
            str += `;expires=${d.toUTCString()}`
        }
        document.cookie = str;
    },

    /**
     * 取cookie
     * @param {string} key
     * @return {string} return 返回cookie的值
     */
    getCookie(key){
        var str = document.cookie
        var coo = str.split('; ')
        var obj = {}
        coo.forEach(ele =>{
            var arr = ele.split('=')
            obj[arr[0]] = decodeURIComponent(arr[1]) 
        })
        return obj[key]
    },

    /**
     * get发送请求
     * @param {string} url      请求地址
     * @param {object} obj      拼接的对象   
     * @param {function} fn     回调函数
     * @param {boolean} isjson  是否需要转成满足json格式的数组，默认ture
     */
    get(url,obj,fn,isjson=true){
        // 首先 new xmlhttprequest对象
        var xhr = new XMLHttpRequest()
        // 判断obj是否传参，传参的话就拼接到url后面
        if(obj){
            url = url + '?'
            for(var key in obj){
                url += `${key}=${obj[key]}&`
            }
            url =  url.slice(0,-1);
        }
        // 建立跟后端的连接
        xhr.open('GET',url)
        // 发送请求
        xhr.send()
        // 监听 状态改变
        xhr.onreadystatechange = function () {
            if(xhr.readyState === 4){
                if(xhr.status === 200){
                    isjson ? fn && fn(JSON.parse(xhr.responseText)) : fn && fn(xhr.responseText)
                }
            }
        }
    },

    /**
     * post发送请求
     * @param {string} url      请求地址
     * @param {object} obj      拼接的对象   
     * @param {function} fn     回调函数
     * @param {boolean} isjson  是否需要转成满足json格式的数组，默认ture
     */
    post (url,obj,fn,isjson=true) {
        var str = ''
        if(obj){
            for(var key in obj){
                str += `${key}=${obj[key]}&`
            }
            str = str.slice(0,-1)
        }
        var xhr = new XMLHttpRequest()
        xhr.open('POST',url)
        xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
        xhr.send(str)
        xhr.onreadystatechange = () =>{
            if(xhr.readyState ===4 ){
                if(xhr.status === 200){
                    isjson ? fn && fn(JSON.parse(xhr.responseText)) : fn && fn(xhr.responseText)
                }
            }
        }
    },
    
    /**
     * ajax处理post或者get请求
     * @param {object}   obj    请求方式，地址及参数{method:post,url:....,id:4}
     * @param {function} fn     回调函数       
     * @param {boolean}  isjson 是否需要转成满足json格式的数组，默认ture
     */
    ajax(method,url,obj,fn,isjson=true){
        if(method === 'POST' || method === 'post'){
            this.post(url,obj,fn,isjson=true)
        }
        if(method === 'GET' || method === 'get'){
            this.get(url,obj,fn,isjson=true)
        }
    },
    
    /**
     * jsonp 请求 跨域请求
     * @param {string}  url  请求地址  
     * @param {string}  cbName   函数名字
     * @param {object}  obj  其他参数
     */
    jsonp(url,cbName,obj){
        url += `?cb=${cbName}`
        if(obj){
            for(var key in obj){
                url += `&${key}=${obj[key]}`
            }
        }
        var script = document.createElement('script')
        script.src = url
        document.body.appendChild(script)
        document.body.removeChild(script)
    },

    /**
     * get-promise发送请求
     * @param {string} url      请求地址
     * @param {object} obj      拼接的对象
     * @param {boolean} isjson  是否需要转成满足json格式的数组，默认ture
     */

    getFetch(url,obj,isjson=true){
        if(obj){
            url += '?'
            for(var key in obj){
                url += `${key}=${obj[key]}&`
            }
            url = url.slice(0,-1)
        }
        return new Promise((reslove,reject) =>{
            var xhr = new XMLHttpRequest()
            xhr.open('GET',url)
            xhr.send()
            xhr.onreadystatechange = () =>{
                if(xhr.readyState === 4){
                    if(xhr.status === 200){
                        var data = isjson ? JSON.parse(xhr.responseText) : xhr.responseText
                        reslove(data)
                    }else{
                        reject()
                    }
                }
            }
        })
    },

    /**
     * post-promise发送请求
     * @param {string} url      请求地址
     * @param {object} obj      拼接的对象
     * @param {boolean} isjson  是否需要转成满足json格式的数组，默认ture
     */
    postFetch(url,obj,isjson=true){
        var str = ''
        if(obj){
            for(var key in obj){
                str += `${key}=${obj[key]}&`
            }
            str = str.slice(0,-1)
        }
        return new Promise((reslove,reject) =>{
            var xhr = new XMLHttpRequest()
            xhr.open('POST',url)
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
            xhr.send(str)
            xhr.onreadystatechange = function () {
                if(xhr.readyState === 4){
                    if(xhr.status === 200){
                        var data = isjson ? JSON.parse(xhr.responseText) : xhr.responseText
                        reslove(data)
                    }else{
                        reject()
                    }
                }
            }
        })
    }
    
}